home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume13 / ratfor < prev    next >
Encoding:
Internet Message Format  |  1988-02-27  |  53.4 KB

  1. Subject:  v13i037:  Public domain RATFOR in C
  2. Newsgroups: comp.sources.unix
  3. Sender: sources
  4. Approved: rsalz@uunet.UU.NET
  5.  
  6. Submitted-by: Ozan Yigit <yunexus!oz>
  7. Posting-number: Volume 13, Issue 37
  8. Archive-name: ratfor
  9.  
  10. [  This is a pre-processor that turns RATFOR programs in to real Fortran
  11.    programs.  RATFOR is Fortran with real control structures, like
  12.    switch and if/then/else.  This happens to generate F77 Fortran, too.
  13.    --r$  ]
  14.  
  15. #! /bin/sh
  16. # This is a shell archive, meaning:
  17. # 1. Remove everything above the #! /bin/sh line.
  18. # 2. Save the resulting text in a file.
  19. # 3. Execute the file with /bin/sh (not csh) to create the files:
  20. #    rat4.c
  21. #    lookup.c
  22. #    getopt.c
  23. #    ratdef.h
  24. #    ratcom.h
  25. #    lookup.h
  26. #    README
  27. #    ratfor.doc
  28. #    test.r
  29. #    makefile
  30. export PATH; PATH=/bin:$PATH
  31. echo shar: extracting "'rat4.c'" '(33966 characters)'
  32. if test -f 'rat4.c'
  33. then
  34.     echo shar: will not over-write existing file "'rat4.c'"
  35. else
  36. sed 's/^    X//' << \SHAR_EOF > 'rat4.c'
  37.     X/*
  38.     X * ratfor - A ratfor pre-processor in C. 
  39.     X * Derived from a pre-processor distributed by the
  40.     X * University of Arizona. Closely corresponds to the
  41.     X * pre-processor described in the "SOFTWARE TOOLS" book.
  42.     X *
  43.     X * By: oz
  44.     X *
  45.     X * Not deived from AT&T code.
  46.     X *
  47.     X * This code is in the public domain. In other words, all rights
  48.     X * are granted to all recipients, "public" at large.
  49.     X *
  50.     X * Modification history:
  51.     X * 
  52.     X * June 1985
  53.     X *    - Ken Yap's mods for F77 output. Currently
  54.     X *      available thru #define F77.
  55.     X *    - Two minor bug-fixes for sane output.
  56.     X * June 1985
  57.     X *    - Improve front-end with getopt().
  58.     X *      User may specify -l n for starting label.
  59.     X *    - Retrofit switch statement handling. This code 
  60.     X *      is borrowed from the SWTOOLS Ratfor.
  61.     X *
  62.     X */
  63.     X
  64.     X#include <stdio.h>
  65.     X#include "ratdef.h"
  66.     X#include "ratcom.h"
  67.     X
  68.     X/* keywords: */
  69.     X
  70.     Xchar sdo[3] = {
  71.     X    LETD,LETO,EOS};
  72.     Xchar vdo[2] = {
  73.     X    LEXDO,EOS};
  74.     X
  75.     Xchar sif[3] = {
  76.     X    LETI,LETF,EOS};
  77.     Xchar vif[2] = {
  78.     X    LEXIF,EOS};
  79.     X
  80.     Xchar selse[5] = {
  81.     X    LETE,LETL,LETS,LETE,EOS};
  82.     Xchar velse[2] = {
  83.     X    LEXELSE,EOS};
  84.     X
  85.     X#ifdef F77
  86.     Xchar sthen[5] = {
  87.     X    LETT,LETH,LETE,LETN,EOS};
  88.     X
  89.     Xchar sendif[6] = {
  90.     X    LETE,LETN,LETD,LETI,LETF,EOS};
  91.     X
  92.     X#endif F77
  93.     Xchar swhile[6] = {
  94.     X    LETW, LETH, LETI, LETL, LETE, EOS};
  95.     Xchar vwhile[2] = {
  96.     X    LEXWHILE, EOS};
  97.     X
  98.     Xchar sbreak[6] = {
  99.     X    LETB, LETR, LETE, LETA, LETK, EOS};
  100.     Xchar vbreak[2] = {
  101.     X    LEXBREAK, EOS};
  102.     X
  103.     Xchar snext[5] = {
  104.     X    LETN,LETE, LETX, LETT, EOS};
  105.     Xchar vnext[2] = {
  106.     X    LEXNEXT, EOS};
  107.     X
  108.     Xchar sfor[4] = {
  109.     X    LETF,LETO, LETR, EOS};
  110.     Xchar vfor[2] = {
  111.     X    LEXFOR, EOS};
  112.     X
  113.     Xchar srept[7] = {
  114.     X    LETR, LETE, LETP, LETE, LETA, LETT, EOS};
  115.     Xchar vrept[2] = {
  116.     X    LEXREPEAT, EOS};
  117.     X
  118.     Xchar suntil[6] = {
  119.     X    LETU, LETN, LETT, LETI, LETL, EOS};
  120.     Xchar vuntil[2] = {
  121.     X    LEXUNTIL, EOS};
  122.     X
  123.     Xchar sswitch[7] = {
  124.     X    LETS, LETW, LETI, LETT, LETC, LETH, EOS};
  125.     Xchar vswitch[2] = {
  126.     X    LEXSWITCH, EOS};
  127.     X
  128.     Xchar scase[5] = {
  129.     X    LETC, LETA, LETS, LETE, EOS};
  130.     Xchar vcase[2] = {
  131.     X    LEXCASE, EOS};
  132.     X
  133.     Xchar sdefault[8] = {
  134.     X    LETD, LETE, LETF, LETA, LETU, LETL, LETT, EOS};
  135.     Xchar vdefault[2] = {
  136.     X    LEXDEFAULT, EOS};
  137.     X
  138.     Xchar sret[7] = {
  139.     X    LETR, LETE, LETT, LETU, LETR, LETN, EOS};
  140.     Xchar vret[2] = {
  141.     X    LEXRETURN, EOS};
  142.     X
  143.     Xchar sstr[7] = {
  144.     X    LETS, LETT, LETR, LETI, LETN, LETG, EOS};
  145.     Xchar vstr[2] = {
  146.     X    LEXSTRING, EOS};
  147.     X
  148.     Xchar deftyp[2] = {
  149.     X    DEFTYPE, EOS};
  150.     X
  151.     X/* constant strings */
  152.     X
  153.     Xchar *errmsg = "error at line ";
  154.     Xchar *in     = " in ";
  155.     Xchar *ifnot  = "if(.not.";
  156.     Xchar *incl   = "include";
  157.     Xchar *fncn   = "function";
  158.     Xchar *def    = "define";
  159.     Xchar *bdef   = "DEFINE";
  160.     Xchar *contin = "continue";
  161.     Xchar *rgoto  = "goto ";
  162.     Xchar *dat    = "data ";
  163.     Xchar *eoss   = "EOS/";
  164.     X
  165.     Xextern char ngetch();
  166.     Xchar *progname;
  167.     Xint startlab = 23000;        /* default start label */
  168.     X 
  169.     X/* 
  170.     X * M A I N   L I N E  &  I N I T
  171.     X */
  172.     X
  173.     Xmain(argc,argv)
  174.     Xint argc;
  175.     Xchar *argv[];
  176.     X{
  177.     X    int c, errflg = 0;
  178.     X    extern int optind;
  179.     X    extern char *optarg;
  180.     X
  181.     X    progname = argv[0];
  182.     X
  183.     X    while ((c=getopt(argc, argv, "Chn:o:6:")) != EOF)
  184.     X    switch (c) {
  185.     X        case 'C':
  186.     X                /* not written yet */
  187.     X            break;
  188.     X        case 'h':
  189.     X                /* not written yet */
  190.     X            break;
  191.     X        case 'l':    /* user sets label */
  192.     X            startlab = atoi(optarg);
  193.     X            break;
  194.     X        case 'o':
  195.     X            if ((freopen(optarg, "w", stdout)) == NULL)
  196.     X                error("can't write %s\n", optarg);
  197.     X            break;
  198.     X        case '6':
  199.     X                /* not written yet */
  200.     X            break;
  201.     X        default:
  202.     X            ++errflg;
  203.     X    }
  204.     X    
  205.     X    if (errflg) {
  206.     X        fprintf(stderr,
  207.     X            "usage: %s [-C][-hx][-l n][-o file][-6x] [file...]\n");
  208.     X        exit(1);
  209.     X    }
  210.     X
  211.     X    /*
  212.     X     * present version can only process one file, sadly.
  213.     X     */
  214.     X    if (optind >= argc)
  215.     X        infile[0] = stdin;
  216.     X    else if ((infile[0] = fopen(argv[optind], "r")) == NULL)
  217.     X        error("cannot read %s\n", argv[optind]);
  218.     X
  219.     X    initvars();
  220.     X
  221.     X    parse();        /* call parser.. */
  222.     X
  223.     X    exit(1);
  224.     X}
  225.     X
  226.     X/*
  227.     X * initialise 
  228.     X */
  229.     Xinitvars()
  230.     X{
  231.     X    int i;
  232.     X
  233.     X    outp = 0;        /* output character pointer */
  234.     X    level = 0;        /* file control */
  235.     X    linect[0] = 1;        /* line count of first file */
  236.     X    fnamp = 0;
  237.     X    fnames[0] = EOS;
  238.     X    bp = -1;        /* pushback buffer pointer */
  239.     X    fordep = 0;        /* for stack */
  240.     X    swtop = 0;        /* switch stack index */
  241.     X    swlast = 1;        /* switch stack index */
  242.     X    for( i = 0; i <= 126; i++)
  243.     X        tabptr[i] = 0;
  244.     X    install(def, deftyp);    /* default definitions */
  245.     X    install(bdef, deftyp);
  246.     X    fcname[0] = EOS;    /* current function name */
  247.     X    label = startlab;    /* next generated label */
  248.     X}
  249.     X
  250.     X/*
  251.     X * P A R S E R
  252.     X */
  253.     X
  254.     Xparse()
  255.     X{
  256.     X    char lexstr[MAXTOK];
  257.     X    int lab, labval[MAXSTACK], lextyp[MAXSTACK], sp, i, token;
  258.     X
  259.     X    sp = 0;
  260.     X    lextyp[0] = EOF;
  261.     X    for (token = lex(lexstr); token != EOF; token = lex(lexstr)) {
  262.     X        if (token == LEXIF)
  263.     X            ifcode(&lab);
  264.     X        else if (token == LEXDO)
  265.     X            docode(&lab);
  266.     X        else if (token == LEXWHILE)
  267.     X            whilec(&lab);
  268.     X        else if (token == LEXFOR)
  269.     X            forcod(&lab);
  270.     X        else if (token == LEXREPEAT)
  271.     X            repcod(&lab);
  272.     X        else if (token == LEXSWITCH)
  273.     X            swcode(&lab);
  274.     X        else if (token == LEXCASE || token == LEXDEFAULT) {
  275.     X            for (i = sp; i >= 0; i--)
  276.     X                if (lextyp[i] == LEXSWITCH)
  277.     X                    break;
  278.     X            if (i < 0)
  279.     X                synerr("illegal case of default.");
  280.     X            else
  281.     X                cascod(labval[i], token);
  282.     X        }
  283.     X        else if (token == LEXDIGITS)
  284.     X            labelc(lexstr);
  285.     X        else if (token == LEXELSE) {
  286.     X            if (lextyp[sp] == LEXIF)
  287.     X                elseif(labval[sp]);
  288.     X            else
  289.     X                synerr("illegal else.");
  290.     X        }
  291.     X        if (token == LEXIF || token == LEXELSE || token == LEXWHILE
  292.     X            || token == LEXFOR || token == LEXREPEAT
  293.     X            || token == LEXDO || token == LEXDIGITS 
  294.     X            || token == LEXSWITCH || token == LBRACE) {
  295.     X            sp++;         /* beginning of statement */
  296.     X            if (sp > MAXSTACK)
  297.     X                baderr("stack overflow in parser.");
  298.     X            lextyp[sp] = token;     /* stack type and value */
  299.     X            labval[sp] = lab;
  300.     X        }
  301.     X        else if (token != LEXCASE && token != LEXDEFAULT) {
  302.     X            /* 
  303.     X                 * end of statement - prepare to unstack 
  304.     X             */
  305.     X            if (token == RBRACE) {
  306.     X                if (lextyp[sp] == LBRACE)
  307.     X                    sp--;
  308.     X                else if (lextyp[sp] == LEXSWITCH) {
  309.     X                    swend(labval[sp]);
  310.     X                    sp--;
  311.     X                }
  312.     X                else
  313.     X                    synerr("illegal right brace.");
  314.     X            }
  315.     X            else if (token == LEXOTHER)
  316.     X                otherc(lexstr);
  317.     X            else if (token == LEXBREAK || token == LEXNEXT)
  318.     X                brknxt(sp, lextyp, labval, token);
  319.     X            else if (token == LEXRETURN)
  320.     X                retcod();
  321.     X             else if (token == LEXSTRING)
  322.     X                strdcl();
  323.     X            token = lex(lexstr);      /* peek at next token */
  324.     X            pbstr(lexstr);
  325.     X            unstak(&sp, lextyp, labval, token);
  326.     X        }
  327.     X    }
  328.     X    if (sp != 0)
  329.     X        synerr("unexpected EOF.");
  330.     X}
  331.     X
  332.     X/*
  333.     X * L E X I C A L  A N A L Y S E R
  334.     X */
  335.     X
  336.     X/*
  337.     X *  alldig - return YES if str is all digits
  338.     X *
  339.     X */
  340.     Xint
  341.     Xalldig(str)
  342.     Xchar str[];
  343.     X{
  344.     X    int i,j;
  345.     X
  346.     X    j = NO;
  347.     X    if (str[0] == EOS)
  348.     X        return(j);
  349.     X    for (i = 0; str[i] != EOS; i++)
  350.     X        if (type(str[i]) != DIGIT)
  351.     X            return(j);
  352.     X    j = YES;
  353.     X    return(j);
  354.     X}
  355.     X
  356.     X
  357.     X/*
  358.     X * balpar - copy balanced paren string
  359.     X *
  360.     X */
  361.     Xbalpar()
  362.     X{
  363.     X    char token[MAXTOK];
  364.     X    int t,nlpar;
  365.     X
  366.     X    if (gnbtok(token, MAXTOK) != LPAREN) {
  367.     X        synerr("missing left paren.");
  368.     X        return;
  369.     X    }
  370.     X    outstr(token);
  371.     X    nlpar = 1;
  372.     X    do {
  373.     X        t = gettok(token, MAXTOK);
  374.     X        if (t==SEMICOL || t==LBRACE || t==RBRACE || t==EOF) {
  375.     X            pbstr(token);
  376.     X            break;
  377.     X        }
  378.     X        if (t == NEWLINE)      /* delete newlines */
  379.     X            token[0] = EOS;
  380.     X        else if (t == LPAREN)
  381.     X            nlpar++;
  382.     X        else if (t == RPAREN)
  383.     X            nlpar--;
  384.     X        /* else nothing special */
  385.     X        outstr(token);
  386.     X    } 
  387.     X    while (nlpar > 0);
  388.     X    if (nlpar != 0)
  389.     X        synerr("missing parenthesis in condition.");
  390.     X}
  391.     X
  392.     X/*
  393.     X * deftok - get token; process macro calls and invocations
  394.     X *
  395.     X */
  396.     Xint
  397.     Xdeftok(token, toksiz, fd)
  398.     Xchar token[];
  399.     Xint toksiz;
  400.     XFILE *fd;
  401.     X{
  402.     X    char defn[MAXDEF];
  403.     X    int t;
  404.     X
  405.     X    for (t=gtok(token, toksiz, fd); t!=EOF; t=gtok(token, toksiz, fd)) {
  406.     X        if (t != ALPHA)   /* non-alpha */
  407.     X            break;
  408.     X        if (look(token, defn) == NO)   /* undefined */
  409.     X            break;
  410.     X        if (defn[0] == DEFTYPE) {   /* get definition */
  411.     X            getdef(token, toksiz, defn, MAXDEF, fd);
  412.     X            install(token, defn);
  413.     X        }
  414.     X        else
  415.     X            pbstr(defn);   /* push replacement onto input */
  416.     X    }
  417.     X    if (t == ALPHA)   /* convert to single case */
  418.     X        fold(token);
  419.     X    return(t);
  420.     X}
  421.     X
  422.     X
  423.     X/*
  424.     X * eatup - process rest of statement; interpret continuations
  425.     X *
  426.     X */
  427.     Xeatup()
  428.     X{
  429.     X
  430.     X    char ptoken[MAXTOK], token[MAXTOK];
  431.     X    int nlpar, t;
  432.     X
  433.     X    nlpar = 0;
  434.     X    do {
  435.     X        t = gettok(token, MAXTOK);
  436.     X        if (t == SEMICOL || t == NEWLINE)
  437.     X            break;
  438.     X        if (t == RBRACE || t == LBRACE) {
  439.     X            pbstr(token);
  440.     X            break;
  441.     X        }
  442.     X        if (t == EOF) {
  443.     X            synerr("unexpected EOF.");
  444.     X            pbstr(token);
  445.     X            break;
  446.     X        }
  447.     X        if (t == COMMA || t == PLUS 
  448.     X                   || t == MINUS || t == STAR || t == LPAREN
  449.     X                       || t == AND || t == BAR || t == BANG
  450.     X                   || t == EQUALS || t == UNDERLINE ) {
  451.     X            while (gettok(ptoken, MAXTOK) == NEWLINE)
  452.     X                ;
  453.     X            pbstr(ptoken);
  454.     X            if (t == UNDERLINE)
  455.     X                token[0] = EOS;
  456.     X        }
  457.     X        if (t == LPAREN)
  458.     X            nlpar++;
  459.     X        else if (t == RPAREN)
  460.     X            nlpar--;
  461.     X        outstr(token);
  462.     X
  463.     X    } while (nlpar >= 0);
  464.     X
  465.     X    if (nlpar != 0)
  466.     X        synerr("unbalanced parentheses.");
  467.     X}
  468.     X
  469.     X/*
  470.     X * getdef (for no arguments) - get name and definition
  471.     X *
  472.     X */
  473.     Xgetdef(token, toksiz, defn, defsiz, fd)
  474.     Xchar token[];
  475.     Xint toksiz;
  476.     Xchar defn[];
  477.     Xint defsiz;
  478.     XFILE *fd;
  479.     X{
  480.     X    int i, nlpar, t;
  481.     X    char c, ptoken[MAXTOK];
  482.     X
  483.     X    skpblk(fd);
  484.     X    /*
  485.     X     * define(name,defn) or
  486.     X     * define name defn
  487.     X     *
  488.     X     */
  489.     X    if ((t = gtok(ptoken, MAXTOK, fd)) != LPAREN) {;
  490.     X        t = BLANK;              /* define name defn */
  491.     X        pbstr(ptoken);
  492.     X    }
  493.     X    skpblk(fd);
  494.     X    if (gtok(token, toksiz, fd) != ALPHA)
  495.     X        baderr("non-alphanumeric name.");
  496.     X    skpblk(fd);
  497.     X    c = (char) gtok(ptoken, MAXTOK, fd);
  498.     X    if (t == BLANK) {         /* define name defn */
  499.     X        pbstr(ptoken);
  500.     X        i = 0;
  501.     X        do {
  502.     X            c = ngetch(&c, fd);
  503.     X            if (i > defsiz)
  504.     X                baderr("definition too long.");
  505.     X            defn[i++] = c;
  506.     X        } 
  507.     X        while (c != SHARP && c != NEWLINE && c != EOF);
  508.     X        if (c == SHARP)
  509.     X            putbak(c);
  510.     X    }
  511.     X    else if (t == LPAREN) {   /* define (name, defn) */
  512.     X        if (c != COMMA)
  513.     X            baderr("missing comma in define.");
  514.     X        /* else got (name, */
  515.     X        nlpar = 0;
  516.     X        for (i = 0; nlpar >= 0; i++)
  517.     X            if (i > defsiz)
  518.     X                baderr("definition too long.");
  519.     X            else if (ngetch(&defn[i], fd) == EOF)
  520.     X                baderr("missing right paren.");
  521.     X            else if (defn[i] == LPAREN)
  522.     X                nlpar++;
  523.     X            else if (defn[i] == RPAREN)
  524.     X                nlpar--;
  525.     X        /* else normal character in defn[i] */
  526.     X    }
  527.     X    else
  528.     X        baderr("getdef is confused.");
  529.     X    defn[i-1] = EOS;
  530.     X}
  531.     X
  532.     X/*
  533.     X * gettok - get token. handles file inclusion and line numbers
  534.     X *
  535.     X */
  536.     Xint
  537.     Xgettok(token, toksiz)
  538.     Xchar token[];
  539.     Xint toksiz;
  540.     X{
  541.     X    int t, i;
  542.     X    int tok;
  543.     X    char name[MAXNAME];
  544.     X
  545.     X    for ( ; level >= 0; level--) {
  546.     X        for (tok = deftok(token, toksiz, infile[level]); tok != EOF;
  547.     X             tok = deftok(token, toksiz, infile[level])) {
  548.     X                if (equal(token, fncn) == YES) {
  549.     X                skpblk(infile[level]);
  550.     X                t = deftok(fcname, MAXNAME, infile[level]);
  551.     X                pbstr(fcname);
  552.     X                if (t != ALPHA)
  553.     X                    synerr("missing function name.");
  554.     X                putbak(BLANK);
  555.     X                return(tok);
  556.     X            }
  557.     X            else if (equal(token, incl) == NO)
  558.     X                return(tok);
  559.     X            for (i = 0 ;; i = strlen(name)) {
  560.     X                t = deftok(&name[i], MAXNAME, infile[level]);
  561.     X                if (t == NEWLINE || t == SEMICOL) {
  562.     X                    pbstr(&name[i]);
  563.     X                    break;
  564.     X                }
  565.     X            }
  566.     X            name[i] = EOS;
  567.     X            if (name[1] == SQUOTE) {
  568.     X                outtab();
  569.     X                outstr(token);
  570.     X                outstr(name);
  571.     X                outdon();
  572.     X                eatup();
  573.     X                return(tok);
  574.     X            }
  575.     X            if (level >= NFILES)
  576.     X                synerr("includes nested too deeply.");
  577.     X            else {
  578.     X                infile[level+1] = fopen(name, "r");
  579.     X                linect[level+1] = 1;
  580.     X                if (infile[level+1] == NULL)
  581.     X                    synerr("can't open include.");
  582.     X                else {
  583.     X                    level++;
  584.     X                    if (fnamp + i <= MAXFNAMES) {
  585.     X                        scopy(name, 0, fnames, fnamp);
  586.     X                        fnamp = fnamp + i;    /* push file name stack */
  587.     X                    }
  588.     X                }
  589.     X            }
  590.     X        }
  591.     X        if (level > 0) {      /* close include and pop file name stack */
  592.     X            fclose(infile[level]);
  593.     X            for (fnamp--; fnamp > 0; fnamp--)
  594.     X                if (fnames[fnamp-1] == EOS)
  595.     X                    break;
  596.     X        }
  597.     X    }
  598.     X    token[0] = EOF;   /* in case called more than once */
  599.     X    token[1] = EOS;
  600.     X    tok = EOF;
  601.     X    return(tok);
  602.     X}
  603.     X
  604.     X/*
  605.     X * gnbtok - get nonblank token
  606.     X *
  607.     X */
  608.     Xint
  609.     Xgnbtok(token, toksiz)
  610.     Xchar token[];
  611.     Xint toksiz;
  612.     X{
  613.     X    int tok;
  614.     X
  615.     X    skpblk(infile[level]);
  616.     X    tok = gettok(token, toksiz);
  617.     X    return(tok);
  618.     X}
  619.     X
  620.     X/*
  621.     X * gtok - get token for Ratfor
  622.     X *
  623.     X */
  624.     Xint
  625.     Xgtok(lexstr, toksiz, fd)
  626.     Xchar lexstr[];
  627.     Xint toksiz;
  628.     XFILE *fd;
  629.     X{
  630.     X    int i, b, n, tok; 
  631.     X    char c;
  632.     X    c = ngetch(&lexstr[0], fd);
  633.     X    if (c == BLANK || c == TAB) {
  634.     X        lexstr[0] = BLANK;
  635.     X        while (c == BLANK || c == TAB)    /* compress many blanks to one */
  636.     X            c = ngetch(&c, fd);
  637.     X        if (c == SHARP)
  638.     X            while (ngetch(&c, fd) != NEWLINE)   /* strip comments */
  639.     X                ;
  640.     X        if (c != NEWLINE)
  641.     X            putbak(c);
  642.     X        else
  643.     X            lexstr[0] = NEWLINE;
  644.     X        lexstr[1] = EOS;
  645.     X        return((int)lexstr[0]);
  646.     X    }
  647.     X    i = 0;
  648.     X    tok = type(c);
  649.     X    if (tok == LETTER) {    /* alpha */
  650.     X        for (i = 0; i < toksiz - 3; i++) {
  651.     X            tok = type(ngetch(&lexstr[i+1], fd));
  652.     X            /* Test for DOLLAR added by BM, 7-15-80 */
  653.     X            if (tok != LETTER && tok != DIGIT 
  654.     X                && tok != UNDERLINE && tok!=DOLLAR
  655.     X                && tok != PERIOD)
  656.     X                break;
  657.     X        }
  658.     X        putbak(lexstr[i+1]);
  659.     X        tok = ALPHA;
  660.     X    }
  661.     X    else if (tok == DIGIT) {    /* digits */
  662.     X        b = c - DIG0;    /* in case alternate base number */
  663.     X        for (i = 0; i < toksiz - 3; i++) {
  664.     X            if (type(ngetch(&lexstr[i+1], fd)) != DIGIT)
  665.     X                break;
  666.     X            b = 10*b + lexstr[i+1] - DIG0;
  667.     X        }
  668.     X        if (lexstr[i+1] == RADIX && b >= 2 && b <= 36) {   
  669.     X            /* n%ddd... */
  670.     X            for (n = 0;; n = b*n + c - DIG0) {
  671.     X                c = ngetch(&lexstr[0], fd);
  672.     X                if (c >= LETA && c <= LETZ)
  673.     X                    c = c - LETA + DIG9 + 1;
  674.     X                else if (c >= BIGA && c <= BIGZ)
  675.     X                    c = c - BIGA + DIG9 + 1;
  676.     X                if (c < DIG0 || c >= DIG0 + b)
  677.     X                    break;
  678.     X            }
  679.     X            putbak(lexstr[0]);
  680.     X            i = itoc(n, lexstr, toksiz);
  681.     X        }
  682.     X        else
  683.     X            putbak(lexstr[i+1]);
  684.     X        tok = DIGIT;
  685.     X    }
  686.     X#ifdef SQUAREB
  687.     X    else if (c == LBRACK) {   /* allow [ for { */
  688.     X        lexstr[0] = LBRACE;
  689.     X        tok = LBRACE;
  690.     X    }
  691.     X    else if (c == RBRACK) {   /* allow ] for } */
  692.     X        lexstr[0] = RBRACE;
  693.     X        tok = RBRACE;
  694.     X    }
  695.     X#endif
  696.     X    else if (c == SQUOTE || c == DQUOTE) {
  697.     X        for (i = 1; ngetch(&lexstr[i], fd) != lexstr[0]; i++) {
  698.     X            if (lexstr[i] == UNDERLINE)
  699.     X                if (ngetch(&c, fd) == NEWLINE) {
  700.     X                    while (c == NEWLINE || c == BLANK || c == TAB)
  701.     X                        c = ngetch(&c, fd);
  702.     X                    lexstr[i] = c;
  703.     X                }
  704.     X                else
  705.     X                    putbak(c);
  706.     X            if (lexstr[i] == NEWLINE || i >= toksiz-1) {
  707.     X                synerr("missing quote.");
  708.     X                lexstr[i] = lexstr[0];
  709.     X                putbak(NEWLINE);
  710.     X                break;
  711.     X            }
  712.     X        }
  713.     X    }
  714.     X    else if (c == SHARP) {   /* strip comments */
  715.     X        while (ngetch(&lexstr[0], fd) != NEWLINE)
  716.     X            ;
  717.     X        tok = NEWLINE;
  718.     X    }
  719.     X    else if (c == GREATER || c == LESS || c == NOT 
  720.     X         || c == BANG || c == CARET || c == EQUALS 
  721.     X         || c == AND || c == OR)
  722.     X        i = relate(lexstr, fd);
  723.     X    if (i >= toksiz-1)
  724.     X        synerr("token too long.");
  725.     X    lexstr[i+1] = EOS;
  726.     X    if (lexstr[0] == NEWLINE)
  727.     X        linect[level] = linect[level] + 1;
  728.     X    return(tok);
  729.     X}
  730.     X
  731.     X/*
  732.     X * lex - return lexical type of token
  733.     X *
  734.     X */
  735.     Xint
  736.     Xlex(lexstr)
  737.     Xchar lexstr[];
  738.     X{
  739.     X
  740.     X    int tok;
  741.     X
  742.     X    for (tok = gnbtok(lexstr, MAXTOK);
  743.     X         tok == NEWLINE; tok = gnbtok(lexstr, MAXTOK))
  744.     X            ;
  745.     X    if (tok == EOF || tok == SEMICOL || tok == LBRACE || tok == RBRACE)
  746.     X        return(tok);
  747.     X    if (tok == DIGIT)
  748.     X        tok = LEXDIGITS;
  749.     X    else if (equal(lexstr, sif) == YES)
  750.     X        tok = vif[0];
  751.     X    else if (equal(lexstr, selse) == YES)
  752.     X        tok = velse[0];
  753.     X    else if (equal(lexstr, swhile) == YES)
  754.     X        tok = vwhile[0];
  755.     X    else if (equal(lexstr, sdo) == YES)
  756.     X        tok = vdo[0];
  757.     X    else if (equal(lexstr, sbreak) == YES)
  758.     X        tok = vbreak[0];
  759.     X    else if (equal(lexstr, snext) == YES)
  760.     X        tok = vnext[0];
  761.     X    else if (equal(lexstr, sfor) == YES)
  762.     X        tok = vfor[0];
  763.     X    else if (equal(lexstr, srept) == YES)
  764.     X        tok = vrept[0];
  765.     X    else if (equal(lexstr, suntil) == YES)
  766.     X        tok = vuntil[0];
  767.     X    else if (equal(lexstr, sswitch) == YES)
  768.     X        tok = vswitch[0];
  769.     X    else if (equal(lexstr, scase) == YES)
  770.     X        tok = vcase[0];
  771.     X    else if (equal(lexstr, sdefault) == YES)
  772.     X        tok = vdefault[0];
  773.     X    else if (equal(lexstr, sret) == YES)
  774.     X        tok = vret[0];
  775.     X    else if (equal(lexstr, sstr) == YES)
  776.     X        tok = vstr[0];
  777.     X    else
  778.     X        tok = LEXOTHER;
  779.     X    return(tok);
  780.     X}
  781.     X
  782.     X/*
  783.     X * ngetch - get a (possibly pushed back) character
  784.     X *
  785.     X */
  786.     Xchar
  787.     Xngetch(c, fd)
  788.     Xchar *c;
  789.     XFILE *fd;
  790.     X{
  791.     X
  792.     X    if (bp >= 0) {
  793.     X        *c = buf[bp];
  794.     X        bp--;
  795.     X    }
  796.     X    else
  797.     X        *c = (char) getc(fd);
  798.     X    
  799.     X    return(*c);
  800.     X}
  801.     X/*
  802.     X * pbstr - push string back onto input
  803.     X *
  804.     X */
  805.     Xpbstr(in)
  806.     Xchar in[];
  807.     X{
  808.     X    int i;
  809.     X
  810.     X    for (i = strlen(in) - 1; i >= 0; i--)
  811.     X        putbak(in[i]);
  812.     X}
  813.     X
  814.     X/*
  815.     X * putbak - push char back onto input
  816.     X *
  817.     X */
  818.     Xputbak(c)
  819.     Xchar c;
  820.     X{
  821.     X
  822.     X    bp++;
  823.     X    if (bp > BUFSIZE)
  824.     X        baderr("too many characters pushed back.");
  825.     X    buf[bp] = c;
  826.     X}
  827.     X
  828.     X
  829.     X/*
  830.     X * relate - convert relational shorthands into long form
  831.     X *
  832.     X */
  833.     Xint
  834.     Xrelate(token, fd)
  835.     Xchar token[];
  836.     XFILE *fd;
  837.     X{
  838.     X
  839.     X    if (ngetch(&token[1], fd) != EQUALS) {
  840.     X        putbak(token[1]);
  841.     X        token[2] = LETT;
  842.     X    }
  843.     X    else
  844.     X        token[2] = LETE;
  845.     X    token[3] = PERIOD;
  846.     X    token[4] = EOS;
  847.     X    token[5] = EOS;    /* for .not. and .and. */
  848.     X    if (token[0] == GREATER)
  849.     X        token[1] = LETG;
  850.     X    else if (token[0] == LESS)
  851.     X        token[1] = LETL;
  852.     X    else if (token[0] == NOT || token[0] == BANG || token[0] == CARET) {
  853.     X        if (token[1] != EQUALS) {
  854.     X            token[2] = LETO;
  855.     X            token[3] = LETT;
  856.     X            token[4] = PERIOD;
  857.     X        }
  858.     X        token[1] = LETN;
  859.     X    }
  860.     X    else if (token[0] == EQUALS) {
  861.     X        if (token[1] != EQUALS) {
  862.     X            token[2] = EOS;
  863.     X            return(0);
  864.     X        }
  865.     X        token[1] = LETE;
  866.     X        token[2] = LETQ;
  867.     X    }
  868.     X    else if (token[0] == AND) {
  869.     X        token[1] = LETA;
  870.     X        token[2] = LETN;
  871.     X        token[3] = LETD;
  872.     X        token[4] = PERIOD;
  873.     X    }
  874.     X    else if (token[0] == OR) {
  875.     X        token[1] = LETO;
  876.     X        token[2] = LETR;
  877.     X    }
  878.     X    else   /* can't happen */
  879.     X        token[1] = EOS;
  880.     X    token[0] = PERIOD;
  881.     X    return(strlen(token)-1);
  882.     X}
  883.     X
  884.     X/*
  885.     X * skpblk - skip blanks and tabs in file  fd
  886.     X *
  887.     X */
  888.     Xskpblk(fd)
  889.     XFILE *fd;
  890.     X{
  891.     X    char c;
  892.     X
  893.     X    for (c = ngetch(&c, fd); c == BLANK || c == TAB; c = ngetch(&c, fd))
  894.     X        ;
  895.     X    putbak(c);
  896.     X}
  897.     X
  898.     X
  899.     X/* 
  900.     X * type - return LETTER, DIGIT or char; works with ascii alphabet
  901.     X *
  902.     X */
  903.     Xint
  904.     Xtype(c)
  905.     Xchar c;
  906.     X{
  907.     X    int t;
  908.     X
  909.     X    if (c >= DIG0 && c <= DIG9)
  910.     X        t = DIGIT;
  911.     X    else if (c >= LETA && c <= LETZ)
  912.     X        t = LETTER;
  913.     X    else if (c >= BIGA && c <= BIGZ)
  914.     X        t = LETTER;
  915.     X    else
  916.     X        t = c;
  917.     X    return(t);
  918.     X}
  919.     X
  920.     X/*
  921.     X * C O D E  G E N E R A T I O N 
  922.     X */
  923.     X
  924.     X/*
  925.     X * brknxt - generate code for break n and next n; n = 1 is default
  926.     X */
  927.     Xbrknxt(sp, lextyp, labval, token)
  928.     Xint sp;
  929.     Xint lextyp[];
  930.     Xint labval[];
  931.     Xint token;
  932.     X{
  933.     X    int i, n;
  934.     X    char t, ptoken[MAXTOK];
  935.     X
  936.     X    n = 0;
  937.     X    t = gnbtok(ptoken, MAXTOK);
  938.     X    if (alldig(ptoken) == YES) {     /* have break n or next n */
  939.     X        i = 0;
  940.     X        n = ctoi(ptoken, &i) - 1;
  941.     X    }
  942.     X    else if (t != SEMICOL)      /* default case */
  943.     X        pbstr(ptoken);
  944.     X    for (i = sp; i >= 0; i--)
  945.     X        if (lextyp[i] == LEXWHILE || lextyp[i] == LEXDO
  946.     X            || lextyp[i] == LEXFOR || lextyp[i] == LEXREPEAT) {
  947.     X            if (n > 0) {
  948.     X                n--;
  949.     X                continue;             /* seek proper level */
  950.     X            }
  951.     X            else if (token == LEXBREAK)
  952.     X                outgo(labval[i]+1);
  953.     X            else
  954.     X                outgo(labval[i]);
  955.     X            xfer = YES;
  956.     X            return;
  957.     X        }
  958.     X    if (token == LEXBREAK)
  959.     X        synerr("illegal break.");
  960.     X    else
  961.     X        synerr("illegal next.");
  962.     X    return;
  963.     X}
  964.     X
  965.     X/*
  966.     X * docode - generate code for beginning of do
  967.     X *
  968.     X */
  969.     Xdocode(lab)
  970.     Xint *lab;
  971.     X{
  972.     X    xfer = NO;
  973.     X    outtab();
  974.     X    outstr(sdo);
  975.     X    *lab = labgen(2);
  976.     X    outnum(*lab);
  977.     X    eatup();
  978.     X    outdon();
  979.     X}
  980.     X
  981.     X/*
  982.     X * dostat - generate code for end of do statement
  983.     X *
  984.     X */
  985.     Xdostat(lab)
  986.     Xint lab;
  987.     X{
  988.     X    outcon(lab);
  989.     X    outcon(lab+1);
  990.     X}
  991.     X
  992.     X/*
  993.     X * elseif - generate code for end of if before else
  994.     X *
  995.     X */
  996.     Xelseif(lab)
  997.     Xint lab;
  998.     X{
  999.     X
  1000.     X#ifdef F77
  1001.     X    outtab();
  1002.     X    outstr(selse);
  1003.     X    outdon();
  1004.     X#else
  1005.     X    outgo(lab+1);
  1006.     X    outcon(lab);
  1007.     X#endif F77
  1008.     X}
  1009.     X
  1010.     X/*
  1011.     X * forcod - beginning of for statement
  1012.     X *
  1013.     X */
  1014.     Xforcod(lab)
  1015.     Xint *lab;
  1016.     X{
  1017.     X    char t, token[MAXTOK];
  1018.     X    int i, j, nlpar,tlab;
  1019.     X
  1020.     X    tlab = *lab;
  1021.     X    tlab = labgen(3);
  1022.     X    outcon(0);
  1023.     X    if (gnbtok(token, MAXTOK) != LPAREN) {
  1024.     X        synerr("missing left paren.");
  1025.     X        return;
  1026.     X    }
  1027.     X    if (gnbtok(token, MAXTOK) != SEMICOL) {   /* real init clause */
  1028.     X        pbstr(token);
  1029.     X        outtab();
  1030.     X        eatup();
  1031.     X        outdon();
  1032.     X    }
  1033.     X    if (gnbtok(token, MAXTOK) == SEMICOL)   /* empty condition */
  1034.     X        outcon(tlab);
  1035.     X    else {   /* non-empty condition */
  1036.     X        pbstr(token);
  1037.     X        outnum(tlab);
  1038.     X        outtab();
  1039.     X        outstr(ifnot);
  1040.     X        outch(LPAREN);
  1041.     X        nlpar = 0;
  1042.     X        while (nlpar >= 0) {
  1043.     X            t = gettok(token, MAXTOK);
  1044.     X            if (t == SEMICOL)
  1045.     X                break;
  1046.     X            if (t == LPAREN)
  1047.     X                nlpar++;
  1048.     X            else if (t == RPAREN)
  1049.     X                nlpar--;
  1050.     X            if (t == EOF) {
  1051.     X                pbstr(token);
  1052.     X                return;
  1053.     X            }
  1054.     X            if (t != NEWLINE && t != UNDERLINE)
  1055.     X                outstr(token);
  1056.     X        }
  1057.     X        outch(RPAREN);
  1058.     X        outch(RPAREN);
  1059.     X        outgo((tlab)+2);
  1060.     X        if (nlpar < 0)
  1061.     X            synerr("invalid for clause.");
  1062.     X    }
  1063.     X    fordep++;        /* stack reinit clause */
  1064.     X    j = 0;
  1065.     X    for (i = 1; i < fordep; i++)   /* find end *** should i = 1 ??? *** */
  1066.     X        j = j + strlen(&forstk[j]) + 1;
  1067.     X    forstk[j] = EOS;   /* null, in case no reinit */
  1068.     X    nlpar = 0;
  1069.     X    t = gnbtok(token, MAXTOK);
  1070.     X    pbstr(token);
  1071.     X    while (nlpar >= 0) {
  1072.     X        t = gettok(token, MAXTOK);
  1073.     X        if (t == LPAREN)
  1074.     X            nlpar++;
  1075.     X        else if (t == RPAREN)
  1076.     X            nlpar--;
  1077.     X        if (t == EOF) {
  1078.     X            pbstr(token);
  1079.     X            break;
  1080.     X        }
  1081.     X        if (nlpar >= 0 && t != NEWLINE && t != UNDERLINE) {
  1082.     X            if (j + strlen(token) >= MAXFORSTK)
  1083.     X                baderr("for clause too long.");
  1084.     X            scopy(token, 0, forstk, j);
  1085.     X            j = j + strlen(token);
  1086.     X        }
  1087.     X    }
  1088.     X    tlab++;   /* label for next's */
  1089.     X    *lab = tlab;
  1090.     X}
  1091.     X
  1092.     X/*
  1093.     X * fors - process end of for statement
  1094.     X *
  1095.     X */
  1096.     Xfors(lab)
  1097.     Xint lab;
  1098.     X{
  1099.     X    int i, j;
  1100.     X
  1101.     X    xfer = NO;
  1102.     X    outnum(lab);
  1103.     X    j = 0;
  1104.     X    for (i = 1; i < fordep; i++)
  1105.     X        j = j + strlen(&forstk[j]) + 1;
  1106.     X    if (strlen(&forstk[j]) > 0) {
  1107.     X        outtab();
  1108.     X        outstr(&forstk[j]);
  1109.     X        outdon();
  1110.     X    }
  1111.     X    outgo(lab-1);
  1112.     X    outcon(lab+1);
  1113.     X    fordep--;
  1114.     X}
  1115.     X
  1116.     X/*
  1117.     X * ifcode - generate initial code for if
  1118.     X *
  1119.     X */
  1120.     Xifcode(lab)
  1121.     Xint *lab;
  1122.     X{
  1123.     X
  1124.     X    xfer = NO;
  1125.     X    *lab = labgen(2);
  1126.     X#ifdef F77
  1127.     X    ifthen();
  1128.     X#else
  1129.     X    ifgo(*lab);
  1130.     X#endif F77
  1131.     X}
  1132.     X
  1133.     X#ifdef F77
  1134.     X/*
  1135.     X * ifend - generate code for end of if
  1136.     X *
  1137.     X */
  1138.     Xifend()
  1139.     X{
  1140.     X    outtab();
  1141.     X    outstr(sendif);
  1142.     X    outdon();
  1143.     X}
  1144.     X#endif F77
  1145.     X
  1146.     X/*
  1147.     X * ifgo - generate "if(.not.(...))goto lab"
  1148.     X *
  1149.     X */
  1150.     Xifgo(lab)
  1151.     Xint lab;
  1152.     X{
  1153.     X
  1154.     X    outtab();      /* get to column 7 */
  1155.     X    outstr(ifnot);      /* " if(.not. " */
  1156.     X    balpar();      /* collect and output condition */
  1157.     X    outch(RPAREN);      /* " ) " */
  1158.     X    outgo(lab);         /* " goto lab " */
  1159.     X}
  1160.     X
  1161.     X#ifdef F77
  1162.     X/*
  1163.     X * ifthen - generate "if((...))then"
  1164.     X *
  1165.     X */
  1166.     Xifthen()
  1167.     X{
  1168.     X    outtab();
  1169.     X    outstr(sif);
  1170.     X    balpar();
  1171.     X    outstr(sthen);
  1172.     X    outdon();
  1173.     X}
  1174.     X#endif F77
  1175.     X
  1176.     X/*
  1177.     X * labelc - output statement number
  1178.     X *
  1179.     X */
  1180.     Xlabelc(lexstr)
  1181.     Xchar lexstr[];
  1182.     X{
  1183.     X
  1184.     X    xfer = NO;   /* can't suppress goto's now */
  1185.     X    if (strlen(lexstr) == 5)   /* warn about 23xxx labels */
  1186.     X        if (atoi(lexstr) >= startlab)
  1187.     X            synerr("warning: possible label conflict.");
  1188.     X    outstr(lexstr);
  1189.     X    outtab();
  1190.     X}
  1191.     X
  1192.     X/*
  1193.     X * labgen - generate  n  consecutive labels, return first one
  1194.     X *
  1195.     X */
  1196.     Xint
  1197.     Xlabgen(n)
  1198.     Xint n;
  1199.     X{
  1200.     X    int i;
  1201.     X
  1202.     X    i = label;
  1203.     X    label = label + n;
  1204.     X    return(i);
  1205.     X}
  1206.     X
  1207.     X/*
  1208.     X * otherc - output ordinary Fortran statement
  1209.     X *
  1210.     X */
  1211.     Xotherc(lexstr)
  1212.     Xchar lexstr[];
  1213.     X{
  1214.     X    xfer = NO;
  1215.     X    outtab();
  1216.     X    outstr(lexstr);
  1217.     X    eatup();
  1218.     X    outdon();
  1219.     X}
  1220.     X
  1221.     X/*
  1222.     X * outch - put one char into output buffer
  1223.     X *
  1224.     X */
  1225.     Xoutch(c)
  1226.     Xchar c;
  1227.     X{
  1228.     X    int i;
  1229.     X
  1230.     X    if (outp >= 72) {   /* continuation card */
  1231.     X        outdon();
  1232.     X        for (i = 0; i < 6; i++)
  1233.     X            outbuf[i] = BLANK;
  1234.     X        outp = 6;
  1235.     X    }
  1236.     X    outbuf[outp] = c;
  1237.     X    outp++;
  1238.     X}
  1239.     X
  1240.     X/*
  1241.     X * outcon - output "n   continue"
  1242.     X *
  1243.     X */
  1244.     Xoutcon(n)
  1245.     Xint n;
  1246.     X{
  1247.     X    xfer = NO;
  1248.     X    if (n <= 0 && outp == 0)
  1249.     X        return;            /* don't need unlabeled continues */
  1250.     X    if (n > 0)
  1251.     X        outnum(n);
  1252.     X    outtab();
  1253.     X    outstr(contin);
  1254.     X    outdon();
  1255.     X}
  1256.     X
  1257.     X/*
  1258.     X * outdon - finish off an output line
  1259.     X *
  1260.     X */
  1261.     Xoutdon()
  1262.     X{
  1263.     X
  1264.     X    outbuf[outp] = NEWLINE;
  1265.     X    outbuf[outp+1] = EOS;
  1266.     X    printf("%s", outbuf);
  1267.     X    outp = 0;
  1268.     X}
  1269.     X
  1270.     X/*
  1271.     X * outgo - output "goto  n"
  1272.     X *
  1273.     X */
  1274.     Xoutgo(n)
  1275.     Xint n;
  1276.     X{
  1277.     X    if (xfer == YES)
  1278.     X        return;
  1279.     X    outtab();
  1280.     X    outstr(rgoto);
  1281.     X    outnum(n);
  1282.     X    outdon();
  1283.     X}
  1284.     X
  1285.     X/*
  1286.     X * outnum - output decimal number
  1287.     X *
  1288.     X */
  1289.     Xoutnum(n)
  1290.     Xint n;
  1291.     X{
  1292.     X
  1293.     X    char chars[MAXCHARS];
  1294.     X    int i, m;
  1295.     X
  1296.     X    m = abs(n);
  1297.     X    i = -1;
  1298.     X    do {
  1299.     X        i++;
  1300.     X        chars[i] = (m % 10) + DIG0;
  1301.     X        m = m / 10;
  1302.     X    } 
  1303.     X    while (m > 0 && i < MAXCHARS);
  1304.     X    if (n < 0)
  1305.     X        outch(MINUS);
  1306.     X    for ( ; i >= 0; i--)
  1307.     X        outch(chars[i]);
  1308.     X}
  1309.     X
  1310.     X
  1311.     X 
  1312.     X/*
  1313.     X * outstr - output string
  1314.     X *
  1315.     X */
  1316.     Xoutstr(str)
  1317.     Xchar str[];
  1318.     X{
  1319.     X    int i;
  1320.     X
  1321.     X    for (i=0; str[i] != EOS; i++)
  1322.     X        outch(str[i]);
  1323.     X}
  1324.     X
  1325.     X/*
  1326.     X * outtab - get past column 6
  1327.     X *
  1328.     X */
  1329.     Xouttab()
  1330.     X{
  1331.     X    while (outp < 6)
  1332.     X        outch(BLANK);
  1333.     X}
  1334.     X
  1335.     X
  1336.     X/*
  1337.     X * repcod - generate code for beginning of repeat
  1338.     X *
  1339.     X */
  1340.     Xrepcod(lab)
  1341.     Xint *lab;
  1342.     X{
  1343.     X
  1344.     X    int tlab;
  1345.     X
  1346.     X    tlab = *lab;
  1347.     X    outcon(0);   /* in case there was a label */
  1348.     X    tlab = labgen(3);
  1349.     X    outcon(tlab);
  1350.     X    *lab = ++tlab;        /* label to go on next's */
  1351.     X}
  1352.     X
  1353.     X/*
  1354.     X * retcod - generate code for return
  1355.     X *
  1356.     X */
  1357.     Xretcod()
  1358.     X{
  1359.     X    char token[MAXTOK], t;
  1360.     X
  1361.     X    t = gnbtok(token, MAXTOK);
  1362.     X    if (t != NEWLINE && t != SEMICOL && t != RBRACE) {
  1363.     X        pbstr(token);
  1364.     X        outtab();
  1365.     X        outstr(fcname);
  1366.     X        outch(EQUALS);
  1367.     X        eatup();
  1368.     X        outdon();
  1369.     X    }
  1370.     X    else if (t == RBRACE)
  1371.     X        pbstr(token);
  1372.     X    outtab();
  1373.     X    outstr(sret);
  1374.     X    outdon();
  1375.     X    xfer = YES;
  1376.     X}
  1377.     X
  1378.     X
  1379.     X/* strdcl - generate code for string declaration */
  1380.     Xstrdcl()
  1381.     X{
  1382.     X    char t, name[MAXNAME], init[MAXTOK];
  1383.     X    int i, len;
  1384.     X
  1385.     X    t = gnbtok(name, MAXNAME);
  1386.     X    if (t != ALPHA)
  1387.     X        synerr("missing string name.");
  1388.     X    if (gnbtok(init, MAXTOK) != LPAREN) {  /* make size same as initial value */
  1389.     X        len = strlen(init) + 1;
  1390.     X        if (init[1] == SQUOTE || init[1] == DQUOTE)
  1391.     X            len = len - 2;
  1392.     X    }
  1393.     X    else {    /* form is string name(size) init */
  1394.     X        t = gnbtok(init, MAXTOK);
  1395.     X        i = 0;
  1396.     X        len = ctoi(init, &i);
  1397.     X        if (init[i] != EOS)
  1398.     X            synerr("invalid string size.");
  1399.     X        if (gnbtok(init, MAXTOK) != RPAREN)
  1400.     X            synerr("missing right paren.");
  1401.     X        else
  1402.     X            t = gnbtok(init, MAXTOK);
  1403.     X    }
  1404.     X    outtab();
  1405.     X    /*
  1406.     X    *   outstr(int);
  1407.     X    */
  1408.     X    outstr(name);
  1409.     X    outch(LPAREN);
  1410.     X    outnum(len);
  1411.     X    outch(RPAREN);
  1412.     X    outdon();
  1413.     X    outtab();
  1414.     X    outstr(dat);
  1415.     X    len = strlen(init) + 1;
  1416.     X    if (init[0] == SQUOTE || init[0] == DQUOTE) {
  1417.     X        init[len-1] = EOS;
  1418.     X        scopy(init, 1, init, 0);
  1419.     X        len = len - 2;
  1420.     X    }
  1421.     X    for (i = 1; i <= len; i++) {    /* put out variable names */
  1422.     X        outstr(name);
  1423.     X        outch(LPAREN);
  1424.     X        outnum(i);
  1425.     X        outch(RPAREN);
  1426.     X        if (i < len)
  1427.     X            outch(COMMA);
  1428.     X        else
  1429.     X            outch(SLASH);
  1430.     X        ;
  1431.     X    }
  1432.     X    for (i = 0; init[i] != EOS; i++) {    /* put out init */
  1433.     X        outnum(init[i]);
  1434.     X        outch(COMMA);
  1435.     X    }
  1436.     X    pbstr(eoss);    /* push back EOS for subsequent substitution */
  1437.     X}
  1438.     X
  1439.     X
  1440.     X/*
  1441.     X * unstak - unstack at end of statement
  1442.     X *
  1443.     X */
  1444.     Xunstak(sp, lextyp, labval, token)
  1445.     Xint *sp;
  1446.     Xint lextyp[];
  1447.     Xint labval[];
  1448.     Xchar token;
  1449.     X{
  1450.     X    int tp;
  1451.     X
  1452.     X    tp = *sp;
  1453.     X    for ( ; tp > 0; tp--) {
  1454.     X        if (lextyp[tp] == LBRACE)
  1455.     X            break;
  1456.     X        if (lextyp[tp] == LEXSWITCH)
  1457.     X            break;
  1458.     X        if (lextyp[tp] == LEXIF && token == LEXELSE)
  1459.     X            break;
  1460.     X        if (lextyp[tp] == LEXIF)
  1461.     X#ifdef F77
  1462.     X            ifend();
  1463.     X#else
  1464.     X            outcon(labval[tp]);
  1465.     X#endif F77
  1466.     X        else if (lextyp[tp] == LEXELSE) {
  1467.     X            if (*sp > 1)
  1468.     X                tp--;
  1469.     X#ifdef F77
  1470.     X            ifend();
  1471.     X#else
  1472.     X            outcon(labval[tp]+1);
  1473.     X#endif F77
  1474.     X        }
  1475.     X        else if (lextyp[tp] == LEXDO)
  1476.     X            dostat(labval[tp]);
  1477.     X        else if (lextyp[tp] == LEXWHILE)
  1478.     X            whiles(labval[tp]);
  1479.     X        else if (lextyp[tp] == LEXFOR)
  1480.     X            fors(labval[tp]);
  1481.     X        else if (lextyp[tp] == LEXREPEAT)
  1482.     X            untils(labval[tp], token);
  1483.     X    }
  1484.     X    *sp = tp;
  1485.     X}
  1486.     X
  1487.     X/*
  1488.     X * untils - generate code for until or end of repeat
  1489.     X *
  1490.     X */
  1491.     Xuntils(lab, token)
  1492.     Xint lab;
  1493.     Xint token;
  1494.     X{
  1495.     X    char ptoken[MAXTOK];
  1496.     X
  1497.     X    xfer = NO;
  1498.     X    outnum(lab);
  1499.     X    if (token == LEXUNTIL) {
  1500.     X        lex(ptoken);
  1501.     X        ifgo(lab-1);
  1502.     X    }
  1503.     X    else
  1504.     X        outgo(lab-1);
  1505.     X    outcon(lab+1);
  1506.     X}
  1507.     X
  1508.     X/* 
  1509.     X * whilec - generate code for beginning of while 
  1510.     X *
  1511.     X */
  1512.     Xwhilec(lab)
  1513.     Xint *lab;
  1514.     X{
  1515.     X    int tlab;
  1516.     X
  1517.     X    tlab = *lab;
  1518.     X    outcon(0);         /* unlabeled continue, in case there was a label */
  1519.     X    tlab = labgen(2);
  1520.     X    outnum(tlab);
  1521.     X#ifdef F77
  1522.     X    ifthen();
  1523.     X#else
  1524.     X    ifgo(tlab+1);
  1525.     X#endif F77
  1526.     X    *lab = tlab;
  1527.     X}
  1528.     X
  1529.     X/* 
  1530.     X * whiles - generate code for end of while 
  1531.     X *
  1532.     X */
  1533.     Xwhiles(lab)
  1534.     Xint lab;
  1535.     X{
  1536.     X
  1537.     X    outgo(lab);
  1538.     X#ifdef F77
  1539.     X    ifend();
  1540.     X#endif F77
  1541.     X    outcon(lab+1);
  1542.     X}
  1543.     X
  1544.     X/*
  1545.     X * E R R O R  M E S S A G E S 
  1546.     X */
  1547.     X
  1548.     X/*
  1549.     X *  baderr - print error message, then die
  1550.     X */
  1551.     Xbaderr(msg)
  1552.     Xchar msg[];
  1553.     X{
  1554.     X    synerr(msg);
  1555.     X    exit(1);
  1556.     X}
  1557.     X
  1558.     X/*
  1559.     X * error - print error message with one parameter, then die
  1560.     X */
  1561.     Xerror(msg, s)
  1562.     Xchar *msg, *s;
  1563.     X{
  1564.     X    fprintf(stderr, msg,s);
  1565.     X    exit(1);
  1566.     X}
  1567.     X
  1568.     X/* 
  1569.     X * synerr - report Ratfor syntax error
  1570.     X */
  1571.     Xsynerr(msg)
  1572.     Xchar *msg;
  1573.     X{
  1574.     X    char lc[MAXCHARS];
  1575.     X    int i;
  1576.     X
  1577.     X    fprintf(stderr,errmsg);
  1578.     X    if (level >= 0)
  1579.     X        i = level;
  1580.     X    else
  1581.     X        i = 0;   /* for EOF errors */
  1582.     X    itoc(linect[i], lc, MAXCHARS);
  1583.     X    fprintf(stderr,lc);
  1584.     X    for (i = fnamp - 1; i > 1; i = i - 1)
  1585.     X        if (fnames[i-1] == EOS) {   /* print file name */
  1586.     X            fprintf(stderr,in);
  1587.     X            fprintf(stderr,&fnames[i]);
  1588.     X            break;
  1589.     X        }
  1590.     X    fprintf(stderr,": \n      %s\n",msg);
  1591.     X}
  1592.     X
  1593.     X
  1594.     X/*
  1595.     X * U T I L I T Y  R O U T I N E S
  1596.     X */
  1597.     X
  1598.     X/*
  1599.     X * ctoi - convert string at in[i] to int, increment i
  1600.     X */
  1601.     Xint
  1602.     Xctoi(in, i)
  1603.     Xchar in[];
  1604.     Xint *i;
  1605.     X{
  1606.     X    int k, j;
  1607.     X
  1608.     X    j = *i;
  1609.     X    while (in[j] == BLANK || in[j] == TAB)
  1610.     X        j++;
  1611.     X    for (k = 0; in[j] != EOS; j++) {
  1612.     X        if (in[j] < DIG0 || in[j] > DIG9)
  1613.     X            break;
  1614.     X        k = 10 * k + in[j] - DIG0;
  1615.     X    }
  1616.     X    *i = j;
  1617.     X    return(k);
  1618.     X}
  1619.     X
  1620.     X/*
  1621.     X * fold - convert alphabetic token to single case
  1622.     X *
  1623.     X */
  1624.     Xfold(token)
  1625.     Xchar token[];
  1626.     X{
  1627.     X
  1628.     X    int i;
  1629.     X
  1630.     X    /* WARNING - this routine depends heavily on the */
  1631.     X    /* fact that letters have been mapped into internal */
  1632.     X    /* right-adjusted ascii. god help you if you */
  1633.     X    /* have subverted this mechanism. */
  1634.     X
  1635.     X    for (i = 0; token[i] != EOS; i++)
  1636.     X        if (token[i] >= BIGA && token[i] <= BIGZ)
  1637.     X            token[i] = token[i] - BIGA + LETA;
  1638.     X}
  1639.     X
  1640.     X/*
  1641.     X * equal - compare str1 to str2; return YES if equal, NO if not
  1642.     X *
  1643.     X */
  1644.     Xint
  1645.     Xequal(str1, str2)
  1646.     Xchar str1[];
  1647.     Xchar str2[];
  1648.     X{
  1649.     X    int i;
  1650.     X
  1651.     X    for (i = 0; str1[i] == str2[i]; i++)
  1652.     X        if (str1[i] == EOS)
  1653.     X            return(YES);
  1654.     X    return(NO);
  1655.     X}
  1656.     X
  1657.     X/*
  1658.     X * scopy - copy string at from[i] to to[j]
  1659.     X *
  1660.     X */
  1661.     Xscopy(from, i, to, j)
  1662.     Xchar from[];
  1663.     Xint i;
  1664.     Xchar to[];
  1665.     Xint j;
  1666.     X{
  1667.     X    int k1, k2;
  1668.     X
  1669.     X    k2 = j;
  1670.     X    for (k1 = i; from[k1] != EOS; k1++) {
  1671.     X        to[k2] = from[k1];
  1672.     X        k2++;
  1673.     X    }
  1674.     X    to[k2] = EOS;
  1675.     X}
  1676.     X
  1677.     X#include "lookup.h"
  1678.     X/*
  1679.     X * look - look-up a definition
  1680.     X *
  1681.     X */
  1682.     Xint
  1683.     Xlook(name,defn)
  1684.     Xchar name[];
  1685.     Xchar defn[];
  1686.     X{
  1687.     X    extern struct hashlist *lookup();
  1688.     X    struct hashlist *p;
  1689.     X
  1690.     X    if ((p = lookup(name)) == NULL)
  1691.     X        return(NO);
  1692.     X    (void) strcpy(defn,p->def);
  1693.     X    return(YES);
  1694.     X}
  1695.     X
  1696.     X/*
  1697.     X * itoc - special version of itoa
  1698.     X */
  1699.     Xint
  1700.     Xitoc(n,str,size)
  1701.     Xint n;
  1702.     Xchar str[];
  1703.     Xint size;
  1704.     X{
  1705.     X    int i,j,k,sign;
  1706.     X    char c;
  1707.     X
  1708.     X    if ((sign = n) < 0)
  1709.     X        n = -n;
  1710.     X    i = 0;
  1711.     X    do {
  1712.     X        str[i++] = n % 10 + '0'; 
  1713.     X    } 
  1714.     X    while ((n /= 10) > 0 && i < size-2);
  1715.     X    if (sign < 0 && i < size-1)
  1716.     X        str[i++] = '-';
  1717.     X    str[i] = EOS;
  1718.     X    /*
  1719.     X     * reverse the string and plug it back in
  1720.     X     */
  1721.     X    for (j = 0, k = strlen(str) - 1; j < k; j++, k--) {
  1722.     X        c = str[j];
  1723.     X        str[j] = str[k];
  1724.     X        str[k] = c;
  1725.     X    }
  1726.     X    return(i-1);
  1727.     X}
  1728.     X
  1729.     X/*
  1730.     X * cascod - generate code for case or default label
  1731.     X *
  1732.     X */
  1733.     Xcascod (lab, token)
  1734.     Xint lab;
  1735.     Xint token;
  1736.     X{
  1737.     X    int t, l, lb, ub, i, j, junk;
  1738.     X    char scrtok[MAXTOK];
  1739.     X
  1740.     X    if (swtop <= 0) {
  1741.     X        synerr ("illegal case or default.");
  1742.     X        return;
  1743.     X    }
  1744.     X    outgo(lab + 1);        /* # terminate previous case */
  1745.     X    xfer = YES;
  1746.     X    l = labgen(1);
  1747.     X    if (token == LEXCASE) {     /* # case n[,n]... : ... */
  1748.     X        while (caslab (&lb, &t) != EOF) {
  1749.     X            ub = lb;
  1750.     X            if (t == MINUS)
  1751.     X                junk = caslab (&ub, &t);
  1752.     X            if (lb > ub) {
  1753.     X                synerr ("illegal range in case label.");
  1754.     X                ub = lb;
  1755.     X            }
  1756.     X            if (swlast + 3 > MAXSWITCH)
  1757.     X                baderr ("switch table overflow.");
  1758.     X            for (i = swtop + 3; i < swlast; i = i + 3)
  1759.     X                if (lb <= swstak[i])
  1760.     X                    break;
  1761.     X                else if (lb <= swstak[i+1])
  1762.     X                    synerr ("duplicate case label.");
  1763.     X            if (i < swlast && ub >= swstak[i])
  1764.     X                synerr ("duplicate case label.");
  1765.     X            for (j = swlast; j > i; j--)       /* # insert new entry */
  1766.     X                swstak[j+2] = swstak[j-1];
  1767.     X            swstak[i] = lb;
  1768.     X            swstak[i + 1] = ub;
  1769.     X            swstak[i + 2] = l;
  1770.     X            swstak[swtop + 1] = swstak[swtop + 1]  +  1;
  1771.     X            swlast = swlast + 3;
  1772.     X            if (t == COLON)
  1773.     X                break;
  1774.     X            else if (t != COMMA)
  1775.     X                synerr ("illegal case syntax.");
  1776.     X        }
  1777.     X    }
  1778.     X    else {                       /* # default : ... */
  1779.     X        t = gnbtok (scrtok, MAXTOK);
  1780.     X        if (swstak[swtop + 2] != 0)
  1781.     X            baderr ("multiple defaults in switch statement.");
  1782.     X        else
  1783.     X            swstak[swtop + 2] = l;
  1784.     X    }
  1785.     X
  1786.     X    if (t == EOF)
  1787.     X        synerr ("unexpected EOF.");
  1788.     X    else if (t != COLON)
  1789.     X        baderr ("missing colon in case or default label.");
  1790.     X
  1791.     X    xfer = NO;
  1792.     X    outcon (l);
  1793.     X}
  1794.     X
  1795.     X/*
  1796.     X * caslab - get one case label
  1797.     X *
  1798.     X */
  1799.     Xint
  1800.     Xcaslab (n, t)
  1801.     Xint *n; 
  1802.     Xint *t;
  1803.     X{
  1804.     X    char tok[MAXTOK];
  1805.     X    int i, s;
  1806.     X
  1807.     X    *t = gnbtok (tok, MAXTOK);
  1808.     X    while (*t == NEWLINE)
  1809.     X        *t = gnbtok (tok, MAXTOK);
  1810.     X    if (*t == EOF)
  1811.     X        return (*t);
  1812.     X    if (*t == MINUS)
  1813.     X        s = -1;
  1814.     X    else
  1815.     X        s = 1;
  1816.     X    if (*t == MINUS || *t == PLUS)
  1817.     X        *t = gnbtok (tok, MAXTOK);
  1818.     X    if (*t != DIGIT) {
  1819.     X        synerr ("invalid case label.");
  1820.     X        *n = 0;
  1821.     X    }
  1822.     X    else {
  1823.     X        i = 0;
  1824.     X        *n = s * ctoi (tok, &i);
  1825.     X    }
  1826.     X    *t = gnbtok (tok, MAXTOK);
  1827.     X    while (*t == NEWLINE)
  1828.     X        *t = gnbtok (tok, MAXTOK);
  1829.     X}
  1830.     X
  1831.     X/*
  1832.     X * swcode - generate code for switch stmt.
  1833.     X *
  1834.     X */
  1835.     Xswcode (lab)
  1836.     Xint *lab;
  1837.     X{
  1838.     X    char scrtok[MAXTOK];
  1839.     X
  1840.     X    *lab = labgen (2);
  1841.     X    if (swlast + 3 > MAXSWITCH)
  1842.     X        baderr ("switch table overflow.");
  1843.     X    swstak[swlast] = swtop;
  1844.     X    swstak[swlast + 1] = 0;
  1845.     X    swstak[swlast + 2] = 0;
  1846.     X    swtop = swlast;
  1847.     X    swlast = swlast + 3;
  1848.     X    xfer = NO;
  1849.     X    outtab();      /* # Innn=(e) */
  1850.     X    swvar(*lab);
  1851.     X    outch(EQUALS);
  1852.     X    balpar();
  1853.     X    outdon();
  1854.     X    outgo(*lab);     /* # goto L */
  1855.     X    xfer = YES;
  1856.     X    while (gnbtok (scrtok, MAXTOK) == NEWLINE)
  1857.     X        ;
  1858.     X    if (scrtok[0] != LBRACE) {
  1859.     X        synerr ("missing left brace in switch statement.");
  1860.     X        pbstr (scrtok);
  1861.     X    }
  1862.     X}
  1863.     X
  1864.     X/*
  1865.     X * swend  - finish off switch statement; generate dispatch code
  1866.     X *
  1867.     X */
  1868.     Xswend(lab)
  1869.     Xint lab;
  1870.     X{
  1871.     X    int lb, ub, n, i, j;
  1872.     X
  1873.     Xstatic    char *sif       = "if (";
  1874.     Xstatic    char *slt       = ".lt.1.or.";
  1875.     Xstatic    char *sgt       = ".gt.";
  1876.     Xstatic    char *sgoto     = "goto (";
  1877.     Xstatic    char *seq       = ".eq.";
  1878.     Xstatic    char *sge       = ".ge.";
  1879.     Xstatic    char *sle       = ".le.";
  1880.     Xstatic    char *sand      = ".and.";
  1881.     X
  1882.     X    lb = swstak[swtop + 3];
  1883.     X    ub = swstak[swlast - 2];
  1884.     X    n = swstak[swtop + 1];
  1885.     X    outgo(lab + 1);             /* # terminate last case */
  1886.     X    if (swstak[swtop + 2] == 0)
  1887.     X        swstak[swtop + 2] = lab + 1;    /* # default default label */
  1888.     X    xfer = NO;
  1889.     X    outcon (lab);              /*  L   continue */
  1890.     X    /* output branch table */
  1891.     X    if (n >= CUTOFF && ub - lb < DENSITY * n) {  
  1892.     X        if (lb != 0) {            /* L  Innn=Innn-lb */
  1893.     X            outtab();
  1894.     X            swvar  (lab);
  1895.     X            outch (EQUALS);
  1896.     X            swvar  (lab);
  1897.     X            if (lb < 0)
  1898.     X                outch (PLUS);
  1899.     X            outnum (-lb + 1);
  1900.     X            outdon();
  1901.     X        }
  1902.     X        outtab();  /*  if (Innn.lt.1.or.Innn.gt.ub-lb+1)goto default */
  1903.     X        outstr (sif);
  1904.     X        swvar  (lab);
  1905.     X        outstr (slt);
  1906.     X        swvar  (lab);
  1907.     X        outstr (sgt);
  1908.     X        outnum (ub - lb + 1);
  1909.     X        outch (RPAREN);
  1910.     X        outgo (swstak[swtop + 2]);
  1911.     X        outtab();
  1912.     X        outstr (sgoto);        /* goto ... */
  1913.     X        j = lb;
  1914.     X        for (i = swtop + 3; i < swlast; i = i + 3) {
  1915.     X            /* # fill in vacancies */
  1916.     X            for ( ; j < swstak[i]; j++) {
  1917.     X                outnum(swstak[swtop + 2]);
  1918.     X                outch(COMMA);
  1919.     X            }
  1920.     X            for (j = swstak[i + 1] - swstak[i]; j >= 0; j--)
  1921.     X                outnum(swstak[i + 2]);    /* # fill in range */
  1922.     X            j = swstak[i + 1] + 1;
  1923.     X            if (i < swlast - 3) 
  1924.     X                outch(COMMA);
  1925.     X        }
  1926.     X        outch(RPAREN);
  1927.     X        outch(COMMA);
  1928.     X        swvar(lab);
  1929.     X        outdon();
  1930.     X    }
  1931.     X    else if (n > 0) {         /* # output linear search form */
  1932.     X        for (i = swtop + 3; i < swlast; i = i + 3) {
  1933.     X            outtab();        /* # if (Innn */
  1934.     X            outstr (sif);
  1935.     X            swvar  (lab);
  1936.     X            if (swstak[i] == swstak[i+1]) {
  1937.     X                outstr (seq);     /* #   .eq....*/
  1938.     X                outnum (swstak[i]);
  1939.     X            }
  1940.     X            else {
  1941.     X                outstr (sge);    /* #   .ge.lb.and.Innn.le.ub */
  1942.     X                outnum (swstak[i]);
  1943.     X                outstr (sand);
  1944.     X                swvar  (lab);
  1945.     X                outstr (sle);
  1946.     X                outnum (swstak[i + 1]);
  1947.     X            }
  1948.     X            outch (RPAREN);        /* #    ) goto ... */
  1949.     X            outgo (swstak[i + 2]);
  1950.     X        }
  1951.     X        if (lab + 1 != swstak[swtop + 2])
  1952.     X            outgo (swstak[swtop + 2]);
  1953.     X    }
  1954.     X    outcon (lab + 1);               /* # L+1  continue */
  1955.     X    swlast = swtop;                /* # pop switch stack */
  1956.     X    swtop = swstak[swtop];
  1957.     X}
  1958.     X
  1959.     X/*
  1960.     X * swvar  - output switch variable Innn, where nnn = lab
  1961.     X */
  1962.     Xswvar  (lab)
  1963.     Xint lab;
  1964.     X{
  1965.     X
  1966.     X    outch ('I');
  1967.     X    outnum (lab);
  1968.     X}
  1969. SHAR_EOF
  1970. if test 33966 -ne "`wc -c < 'rat4.c'`"
  1971. then
  1972.     echo shar: error transmitting "'rat4.c'" '(should have been 33966 characters)'
  1973. fi
  1974. chmod +x 'rat4.c'
  1975. fi # end of overwriting check
  1976. echo shar: extracting "'lookup.c'" '(1397 characters)'
  1977. if test -f 'lookup.c'
  1978. then
  1979.     echo shar: will not over-write existing file "'lookup.c'"
  1980. else
  1981. sed 's/^    X//' << \SHAR_EOF > 'lookup.c'
  1982.     X#include <stdio.h>
  1983.     X#include "lookup.h"
  1984.     X
  1985.     Xstatic 
  1986.     Xstruct    hashlist *hashtab[HASHMAX];
  1987.     X
  1988.     X/*
  1989.     X * from K&R "The C Programming language"
  1990.     X * Table lookup routines
  1991.     X *
  1992.     X * hash - for a hash value for string s
  1993.     X *
  1994.     X */
  1995.     Xhash(s)
  1996.     Xchar *s;
  1997.     X{
  1998.     X    int    hashval;
  1999.     X
  2000.     X    for (hashval = 0; *s != '\0';)
  2001.     X        hashval += *s++;
  2002.     X    return (hashval % HASHMAX);
  2003.     X}
  2004.     X
  2005.     X/*
  2006.     X * lookup - lookup for a string s in the hash table
  2007.     X *
  2008.     X */
  2009.     Xstruct hashlist
  2010.     X*lookup(s)
  2011.     Xchar *s;
  2012.     X{
  2013.     X    struct hashlist *np;
  2014.     X
  2015.     X    for (np = hashtab[hash(s)]; np != NULL; np = np->next)
  2016.     X        if (strcmp(s, np->name) == 0)
  2017.     X            return(np);    /* found     */
  2018.     X    return(NULL);        /* not found */
  2019.     X}
  2020.     X
  2021.     X/*
  2022.     X * install - install a string name in hashtable and its value def
  2023.     X *
  2024.     X */
  2025.     Xstruct hashlist
  2026.     X*install(name,def)
  2027.     Xchar *name;
  2028.     Xchar *def;
  2029.     X{
  2030.     X    int hashval;
  2031.     X    struct hashlist *np, *lookup();
  2032.     X    char *strsave(), *malloc();
  2033.     X
  2034.     X    if ((np = lookup(name)) == NULL) {    /* not found.. */
  2035.     X        np = (struct hashlist *) malloc(sizeof(*np));
  2036.     X        if (np == NULL)
  2037.     X            return(NULL);
  2038.     X        if ((np->name = strsave(name)) == NULL)
  2039.     X            return(NULL);
  2040.     X        hashval = hash(np->name);
  2041.     X        np->next = hashtab[hashval];
  2042.     X        hashtab[hashval] = np;
  2043.     X    } else                    /* found..     */
  2044.     X        free(np->def);            /* free prev.  */
  2045.     X    if ((np->def = strsave(def)) == NULL)
  2046.     X        return(NULL);
  2047.     X    return(np);
  2048.     X}
  2049.     X
  2050.     X/*
  2051.     X * strsave - save string s somewhere
  2052.     X *
  2053.     X */
  2054.     Xchar
  2055.     X*strsave(s)
  2056.     Xchar *s;
  2057.     X{
  2058.     X    char *p, *malloc();
  2059.     X
  2060.     X    if ((p = malloc(strlen(s)+1)) != NULL)
  2061.     X        strcpy(p, s);
  2062.     X    return(p);
  2063.     X}
  2064.     X
  2065.     X
  2066. SHAR_EOF
  2067. if test 1397 -ne "`wc -c < 'lookup.c'`"
  2068. then
  2069.     echo shar: error transmitting "'lookup.c'" '(should have been 1397 characters)'
  2070. fi
  2071. chmod +x 'lookup.c'
  2072. fi # end of overwriting check
  2073. echo shar: extracting "'getopt.c'" '(969 characters)'
  2074. if test -f 'getopt.c'
  2075. then
  2076.     echo shar: will not over-write existing file "'getopt.c'"
  2077. else
  2078. sed 's/^    X//' << \SHAR_EOF > 'getopt.c'
  2079.     X/*
  2080.     X * getopt - get option letter from argv
  2081.     X */
  2082.     X
  2083.     X#include <stdio.h>
  2084.     X
  2085.     Xchar    *optarg;    /* Global argument pointer. */
  2086.     Xint    optind = 0;    /* Global argv index. */
  2087.     X
  2088.     Xstatic char    *scan = NULL;    /* Private scan pointer. */
  2089.     X
  2090.     Xextern char    *index();
  2091.     X
  2092.     Xint
  2093.     Xgetopt(argc, argv, optstring)
  2094.     Xint argc;
  2095.     Xchar *argv[];
  2096.     Xchar *optstring;
  2097.     X{
  2098.     X    register char c;
  2099.     X    register char *place;
  2100.     X
  2101.     X    optarg = NULL;
  2102.     X
  2103.     X    if (scan == NULL || *scan == '\0') {
  2104.     X        if (optind == 0)
  2105.     X            optind++;
  2106.     X    
  2107.     X        if (optind >= argc || argv[optind][0] != '-' || argv[optind][1] == '\0')
  2108.     X            return(EOF);
  2109.     X        if (strcmp(argv[optind], "--")==0) {
  2110.     X            optind++;
  2111.     X            return(EOF);
  2112.     X        }
  2113.     X    
  2114.     X        scan = argv[optind]+1;
  2115.     X        optind++;
  2116.     X    }
  2117.     X
  2118.     X    c = *scan++;
  2119.     X    place = index(optstring, c);
  2120.     X
  2121.     X    if (place == NULL || c == ':') {
  2122.     X        fprintf(stderr, "%s: unknown option -%c\n", argv[0], c);
  2123.     X        return('?');
  2124.     X    }
  2125.     X
  2126.     X    place++;
  2127.     X    if (*place == ':') {
  2128.     X        if (*scan != '\0') {
  2129.     X            optarg = scan;
  2130.     X            scan = NULL;
  2131.     X        } else {
  2132.     X            optarg = argv[optind];
  2133.     X            optind++;
  2134.     X        }
  2135.     X    }
  2136.     X
  2137.     X    return(c);
  2138.     X}
  2139.     X   
  2140. SHAR_EOF
  2141. if test 969 -ne "`wc -c < 'getopt.c'`"
  2142. then
  2143.     echo shar: error transmitting "'getopt.c'" '(should have been 969 characters)'
  2144. fi
  2145. chmod +x 'getopt.c'
  2146. fi # end of overwriting check
  2147. echo shar: extracting "'ratdef.h'" '(3579 characters)'
  2148. if test -f 'ratdef.h'
  2149. then
  2150.     echo shar: will not over-write existing file "'ratdef.h'"
  2151. else
  2152. sed 's/^    X//' << \SHAR_EOF > 'ratdef.h'
  2153.     X#define ACCENT  96
  2154.     X#define AND     38
  2155.     X#define APPEND
  2156.     X#define ATSIGN  64
  2157.     X#define BACKSLASH       92
  2158.     X#define BACKSPACE       8
  2159.     X#define BANG    33
  2160.     X#define BAR     124
  2161.     X#define BIGA    65
  2162.     X#define BIGB    66
  2163.     X#define BIGC    67
  2164.     X#define BIGD    68
  2165.     X#define BIGE    69
  2166.     X#define BIGF    70
  2167.     X#define BIGG    71
  2168.     X#define BIGH    72
  2169.     X#define BIGI    73
  2170.     X#define BIGJ    74
  2171.     X#define BIGK    75
  2172.     X#define BIGL    76
  2173.     X#define BIGM    77
  2174.     X#define BIGN    78
  2175.     X#define BIGO    79
  2176.     X#define BIGP    80
  2177.     X#define BIGQ    81
  2178.     X#define BIGR    82
  2179.     X#define BIGS    83
  2180.     X#define BIGT    84
  2181.     X#define BIGU    85
  2182.     X#define BIGV    86
  2183.     X#define BIGW    87
  2184.     X#define BIGX    88
  2185.     X#define BIGY    89
  2186.     X#define BIGZ    90
  2187.     X#define BLANK   32
  2188.     X#define CARET   94
  2189.     X#define COLON   58
  2190.     X#define COMMA   44
  2191.     X#define CRLF    13
  2192.     X#define DIG0    48
  2193.     X#define DIG1    49
  2194.     X#define DIG2    50
  2195.     X#define DIG3    51
  2196.     X#define DIG4    52
  2197.     X#define DIG5    53
  2198.     X#define DIG6    54
  2199.     X#define DIG7    55
  2200.     X#define DIG8    56
  2201.     X#define DIG9    57
  2202.     X#define DOLLAR  36
  2203.     X#define DQUOTE  34
  2204.     X#define EOS     0
  2205.     X#define EQUALS  61
  2206.     X#define ESCAPE  ATSIGN
  2207.     X#define GREATER 62
  2208.     X#define HUGE    30000
  2209.     X#define LBRACE  123
  2210.     X#define LBRACK  91
  2211.     X#define LESS    60
  2212.     X#define LETA    97
  2213.     X#define LETB    98
  2214.     X#define LETC    99
  2215.     X#define LETD    100
  2216.     X#define LETE    101
  2217.     X#define LETF    102
  2218.     X#define LETG    103
  2219.     X#define LETH    104
  2220.     X#define LETI    105
  2221.     X#define LETJ    106
  2222.     X#define LETK    107
  2223.     X#define LETL    108
  2224.     X#define LETM    109
  2225.     X#define LETN    110
  2226.     X#define LETO    111
  2227.     X#define LETP    112
  2228.     X#define LETQ    113
  2229.     X#define LETR    114
  2230.     X#define LETS    115
  2231.     X#define LETT    116
  2232.     X#define LETU    117
  2233.     X#define LETV    118
  2234.     X#define LETW    119
  2235.     X#define LETX    120
  2236.     X#define LETY    121
  2237.     X#define LETZ    122
  2238.     X#define LPAREN  40
  2239.     X#define MINUS   45
  2240.     X#define NEWLINE 10
  2241.     X#define NO      0
  2242.     X#define NOT     126
  2243.     X#define OR      BAR    /* same as | */
  2244.     X#define PERCENT 37
  2245.     X#define PERIOD  46
  2246.     X#define PLUS    43
  2247.     X#define QMARK   63
  2248.     X#define RBRACE  125
  2249.     X#define RBRACK  93
  2250.     X#define RPAREN  41
  2251.     X#define SEMICOL 59
  2252.     X#define SHARP   35
  2253.     X#define SLASH   47
  2254.     X#define SQUOTE  39
  2255.     X#define STAR    42
  2256.     X#define TAB     9
  2257.     X#define TILDE   126
  2258.     X#define UNDERLINE       95
  2259.     X#define YES     1
  2260.     X      
  2261.     X#define LIMIT   134217728
  2262.     X#define LIM1    28
  2263.     X#define LIM2    -28
  2264.     X
  2265.     X/*
  2266.     X * lexical analyser symbols
  2267.     X *
  2268.     X */
  2269.     X
  2270.     X#define LETTER        1
  2271.     X#define DIGIT       2
  2272.     X#define ALPHA       3
  2273.     X#define LEXBREAK       4
  2274.     X#define LEXDIGITS       5
  2275.     X#define LEXDO       6
  2276.     X#define LEXELSE       7
  2277.     X#define LEXFOR       8
  2278.     X#define LEXIF       9
  2279.     X#define LEXNEXT       10
  2280.     X#define LEXOTHER       11
  2281.     X#define LEXREPEAT       12
  2282.     X#define LEXUNTIL       13
  2283.     X#define LEXWHILE       14
  2284.     X#define LEXRETURN       15
  2285.     X#define LEXEND       16
  2286.     X#define LEXSTOP       17
  2287.     X#define LEXSTRING       18
  2288.     X#define LEXSWITCH    19
  2289.     X#define LEXCASE        20
  2290.     X#define LEXDEFAULT    21
  2291.     X#define DEFTYPE       22
  2292.     X
  2293.     X#define MAXCHARS       10       /* characters for outnum */
  2294.     X#define MAXDEF       200       /* max chars in a defn */
  2295.     X#define MAXSWITCH       300     /* max stack for switch statement */
  2296.     X#define CUTOFF          3       /* min number of cases necessary to generate */
  2297.     X                                /* a dispatch table */
  2298.     X#define DENSITY         2
  2299.     X#define MAXFORSTK       200       /* max space for for reinit clauses */
  2300.     X#define MAXFNAMES       350      /* max chars in filename stack NFILES*MAXNAME */
  2301.     X#define MAXNAME       64       /* file name size in gettok */
  2302.     X#define MAXSTACK       100       /* max stack depth for parser */
  2303.     X#define MAXTBL       15000   /* max chars in all definitions */
  2304.     X#define MAXTOK       132       /* max chars in a token */
  2305.     X#define NFILES       7       /* max depth of file inclusion */
  2306.     X
  2307.     X#define RADIX       PERCENT /* % indicates alternate radix */
  2308.     X#define BUFSIZE       300       /* pushback buffer for ngetch and putbak */
  2309.     X
  2310. SHAR_EOF
  2311. if test 3579 -ne "`wc -c < 'ratdef.h'`"
  2312. then
  2313.     echo shar: error transmitting "'ratdef.h'" '(should have been 3579 characters)'
  2314. fi
  2315. chmod +x 'ratdef.h'
  2316. fi # end of overwriting check
  2317. echo shar: extracting "'ratcom.h'" '(1206 characters)'
  2318. if test -f 'ratcom.h'
  2319. then
  2320.     echo shar: will not over-write existing file "'ratcom.h'"
  2321. else
  2322. sed 's/^    X//' << \SHAR_EOF > 'ratcom.h'
  2323.     Xint bp;            /*   next available char; init = 0 */
  2324.     Xchar buf[BUFSIZE];    /*   pushed-back chars */
  2325.     Xchar fcname[MAXNAME];    /*   text of current function name */
  2326.     Xint fordep;        /*   current depth of for statements */
  2327.     Xchar forstk[MAXFORSTK];    /*   stack of reinit strings */
  2328.     Xint swtop;        /*   current switch entry; init=0              */
  2329.     Xint swlast;        /*   next available position; init=1           */
  2330.     Xint swstak[MAXSWITCH];    /*   switch information stack                  */
  2331.     Xint xfer;        /*   YES if just made transfer, NO otherwise */
  2332.     Xint label;        /*   next label returned by labgen */
  2333.     Xint level ;        /*   level of file inclusion; init = 1 */
  2334.     Xint linect[NFILES];    /*   line count on input file[level]; init = 1 */
  2335.     XFILE *infile[NFILES];    /*   file number[level]; init infile[1] = STDIN */
  2336.     Xint fnamp;        /*   next free slot in fnames; init = 2 */
  2337.     Xchar fnames[MAXFNAMES];    /*   stack of include names; init fnames[1] = EOS */
  2338.     Xint avail;        /*   first first location in table; init = 1 */
  2339.     Xint tabptr[127];    /*   name pointers; init = 0 */
  2340.     Xint outp;        /*   last position filled in outbuf; init = 0 */
  2341.     Xchar outbuf[74];    /*   output lines collected here */
  2342.     Xchar fname[MAXNAME][NFILES];    /*   file names */
  2343.     Xint nfiles;        /*   number of files */
  2344. SHAR_EOF
  2345. if test 1206 -ne "`wc -c < 'ratcom.h'`"
  2346. then
  2347.     echo shar: error transmitting "'ratcom.h'" '(should have been 1206 characters)'
  2348. fi
  2349. chmod +x 'ratcom.h'
  2350. fi # end of overwriting check
  2351. echo shar: extracting "'lookup.h'" '(309 characters)'
  2352. if test -f 'lookup.h'
  2353. then
  2354.     echo shar: will not over-write existing file "'lookup.h'"
  2355. else
  2356. sed 's/^    X//' << \SHAR_EOF > 'lookup.h'
  2357.     X
  2358.     X/*
  2359.     X * from K&R "The C Programming language"
  2360.     X * Table lookup routines 
  2361.     X * structure and definitions
  2362.     X *
  2363.     X */
  2364.     X
  2365.     X                    /* basic table entry */
  2366.     Xstruct hashlist {
  2367.     X    char    *name;
  2368.     X    char    *def;
  2369.     X    struct    hashlist *next;        /* next in chain     */
  2370.     X};
  2371.     X
  2372.     X#define HASHMAX    100            /* size of hashtable */
  2373.     X
  2374.     X                    /* hash table itself */
  2375. SHAR_EOF
  2376. if test 309 -ne "`wc -c < 'lookup.h'`"
  2377. then
  2378.     echo shar: error transmitting "'lookup.h'" '(should have been 309 characters)'
  2379. fi
  2380. chmod +x 'lookup.h'
  2381. fi # end of overwriting check
  2382. echo shar: extracting "'README'" '(739 characters)'
  2383. if test -f 'README'
  2384. then
  2385.     echo shar: will not over-write existing file "'README'"
  2386. else
  2387. sed 's/^    X//' << \SHAR_EOF > 'README'
  2388.     X    This is a C version of ratfor, derived from a UofA ratfor
  2389.     X    in ratfor. It was originally released to the net sometime
  2390.     X    ago, and It is re-released for the benefit of those sites
  2391.     X    who only get mod->comp.sources.
  2392.     X
  2393.     X    It now includes minor changes to produce F77 code as well.
  2394.     X    
  2395.     X    This code *is* PD. You (public) have all the rights to the code. 
  2396.     X    [But this also means you (singular) do not have any *extra*
  2397.     X    rights to the code, hence it is impossible for you to restrict
  2398.     X    the use and distribution of this code in any way.]
  2399.     X
  2400.     X    I would, as usual, appreciate hearing about bug fixes and
  2401.     X    improvements.
  2402.     X
  2403.     X    oz
  2404.     X
  2405.     X    Usenet: [decvax|ihnp4]!utzoo!yunexus!oz || 
  2406.     X            ...seismo!mnetor!yunexus!oz
  2407.     X    Bitnet: oz@[yusol|yuyetti].BITNET
  2408.     X    Phonet: [416] 736-5257 x 3976
  2409. SHAR_EOF
  2410. chmod +x 'README'
  2411. fi # end of overwriting check
  2412. echo shar: extracting "'ratfor.doc'" '(2471 characters)'
  2413. if test -f 'ratfor.doc'
  2414. then
  2415.     echo shar: will not over-write existing file "'ratfor.doc'"
  2416. else
  2417. sed 's/^    X//' << \SHAR_EOF > 'ratfor.doc'
  2418.     Xratfor - ratfor preprocessor
  2419.     X     
  2420.     Xsynopsis:
  2421.     X        ratfor [-l n] [-o output] input
  2422.     X     
  2423.     XRatfor has the following syntax:
  2424.     X     
  2425.     Xprog:   stat
  2426.     X        prog stat
  2427.     X     
  2428.     Xstat:   if (...) stat
  2429.     X        if (...) stat else stat
  2430.     X        while (...) stat
  2431.     X        repeat stat
  2432.     X        repeat stat until (...)
  2433.     X        for (...;...;...) stat
  2434.     X        do ... stat
  2435.     X        switch (intexpr) { case val[,val]: stmt ... default: stmt }
  2436.     X        break n
  2437.     X        next n
  2438.     X        return (...)
  2439.     X        digits stat
  2440.     X        { prog }  or  [ prog ]  or  $( prog $)
  2441.     X        anything unrecognizable
  2442.     X     
  2443.     Xwhere stat is any Fortran or Ratfor statement, and intexpr is an
  2444.     Xexpression that resolves into an integer value.  A statement is
  2445.     Xterminated by an end-of-line or a semicolon.  The following translations
  2446.     Xare also performed.
  2447.     X     
  2448.     X        <       .lt.    <=      .le.
  2449.     X        ==      .eq.
  2450.     X        !=      .ne.    ^=      .ne.    ~=      .ne.
  2451.     X        >=      .ge.    >       .gt.
  2452.     X        |       .or.    &       .and.
  2453.     X        !       .not.   ^       .not.   ~       .not.
  2454.     X     
  2455.     XInteger constants in bases other that decimal may be specified as
  2456.     Xn%dddd...  where n is a decimal number indicating the base and dddd...
  2457.     Xare digits in that base.  For bases > 10, letters are used for digits
  2458.     Xabove 9.  Examples:  8%77, 16%2ff, 2%0010011.  The number is converted
  2459.     Xthe equivalent decimal value using multiplication; this may cause sign
  2460.     Xproblems if the number has too many digits.
  2461.     X     
  2462.     XString literals ("..." or '...') can be continued across line boundaries
  2463.     Xby ending the line to be continued with an underline.  The underline is
  2464.     Xnot included as part of the literal.  Leading blanks and tabs on the
  2465.     Xnext line are ignored; this facilitates consistent indentation.
  2466.     X     
  2467.     X        include file
  2468.     X     
  2469.     Xwill include the named file in the input.
  2470.     X     
  2471.     X        define (name,value)     or
  2472.     X        define name value
  2473.     X     
  2474.     Xdefines name as a symbolic parameter with the indicated value.  Names of
  2475.     Xsymbolic parameters may contain letters, digits, periods, and underline
  2476.     Xcharacter but must begin with a letter (e.g.  B.FLAG).  Upper case is
  2477.     Xnot equivalent to lower case in parameter names.
  2478.     X     
  2479.     X        string name "character string"          or
  2480.     X        string name(size) "character string"
  2481.     X     
  2482.     Xdefines name to be an integer array long enough to accomodate the ascii
  2483.     Xcodes for the given character string, one per word.  The last word of
  2484.     Xname is initialized to the symbolic parameter EOS, and indicates the end
  2485.     Xof string.
  2486. SHAR_EOF
  2487. if test 2471 -ne "`wc -c < 'ratfor.doc'`"
  2488. then
  2489.     echo shar: error transmitting "'ratfor.doc'" '(should have been 2471 characters)'
  2490. fi
  2491. chmod +x 'ratfor.doc'
  2492. fi # end of overwriting check
  2493. echo shar: extracting "'test.r'" '(366 characters)'
  2494. if test -f 'test.r'
  2495. then
  2496.     echo shar: will not over-write existing file "'test.r'"
  2497. else
  2498. sed 's/^    X//' << \SHAR_EOF > 'test.r'
  2499.     Xinteger x,y
  2500.     Xx=1; y=2
  2501.     Xif(x == y)
  2502.     X    write(6,600)
  2503.     Xelse if(x > y)
  2504.     X    write(6,601)
  2505.     Xelse
  2506.     X    write(6,602)
  2507.     Xx=1
  2508.     Xwhile(x < 10){
  2509.     X    if(y != 2) break
  2510.     X    if(y != 2) next
  2511.     X    write(6,603)x
  2512.     X    x=x+1
  2513.     X    }
  2514.     Xrepeat
  2515.     X    x=x-1
  2516.     Xuntil(x == 0)
  2517.     Xfor(x=0; x < 10; x=x+1)
  2518.     X    write(6,604)x
  2519.     X600 format('Wrong, x != y')
  2520.     X601 format('Also wrong, x < y')
  2521.     X602 format('Ok!')
  2522.     X603 format('x = ',i2)
  2523.     X604 format('x = ',i2)
  2524.     Xend
  2525. SHAR_EOF
  2526. if test 366 -ne "`wc -c < 'test.r'`"
  2527. then
  2528.     echo shar: error transmitting "'test.r'" '(should have been 366 characters)'
  2529. fi
  2530. chmod +x 'test.r'
  2531. fi # end of overwriting check
  2532. echo shar: extracting "'makefile'" '(488 characters)'
  2533. if test -f 'makefile'
  2534. then
  2535.     echo shar: will not over-write existing file "'makefile'"
  2536. else
  2537. sed 's/^    X//' << \SHAR_EOF > 'makefile'
  2538.     X# pd ratfor (oz)
  2539.     X#
  2540.     X# if F77 is defined, the output
  2541.     X# of ratfor is Fortran 77.
  2542.     X#
  2543.     XCFLAGS = -DF77 -O
  2544.     XDEST = /usr/local/bin
  2545.     XOBJS = rat4.o lookup.o getopt.o
  2546.     XCSRC = rat4.c lookup.c getopt.c
  2547.     XHSRC = ratdef.h ratcom.h lookup.h
  2548.     XDOCS = README ratfor.doc
  2549.     XRSRC = test.r makefile
  2550.     X
  2551.     Xrat4:    ${OBJS}
  2552.     X    cc -o ratfor ${OBJS}
  2553.     X
  2554.     Xrat4.o:        ratdef.h ratcom.h
  2555.     Xlookup.o:    lookup.h
  2556.     X
  2557.     Xinstall: rat4
  2558.     X    install ./ratfor ${DEST}/ratfor
  2559.     Xclean:
  2560.     X    rm -f *.o core ratfor
  2561.     Xpack:
  2562.     X    shar -a ${CSRC} ${HSRC} ${DOCS} ${RSRC} >RATFOR.SHAR
  2563. SHAR_EOF
  2564. if test 488 -ne "`wc -c < 'makefile'`"
  2565. then
  2566.     echo shar: error transmitting "'makefile'" '(should have been 488 characters)'
  2567. fi
  2568. chmod +x 'makefile'
  2569. fi # end of overwriting check
  2570. #    End of shell archive
  2571.